/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023.
 * Description: report when ext4 turn into ro mode
 * Author: Pang LiYuan
 * Create: 2023-09-11
 */
#ifdef CONFIG_RTOS_EXT4_ERROR_NOTIFY
BLOCKING_NOTIFIER_HEAD(ext4_error_notify_chain);

void rtos_save_notify_info(struct super_block *sb, struct rtos_ext4_notify_info *noi)
{
	struct ext4_sb_info *sbi = EXT4_SB(sb);

	spin_lock(&sbi->s_error_lock);
	memcpy(noi->device_name, sb->s_id, sizeof(noi->device_name));
	noi->device_name[sizeof(noi->device_name) - 1] = '\0';

	noi->error_count = sbi->s_add_error_count;
	noi->last_error_code = sbi->s_last_error_code;
	noi->last_error_line = sbi->s_last_error_line;
	noi->last_error_ino = sbi->s_last_error_ino;
	noi->last_error_block = sbi->s_last_error_block;
	noi->last_error_func = sbi->s_last_error_func;
	noi->last_error_time = sbi->s_last_error_time;
	spin_unlock(&sbi->s_error_lock);
}

int rtos_ext4_error_notifier_register(struct notifier_block *nb)
{
	if (nb == NULL || nb->notifier_call == NULL)
		return -EINVAL;

	return blocking_notifier_chain_register(&ext4_error_notify_chain, nb);
}
EXPORT_SYMBOL_NS(rtos_ext4_error_notifier_register, HW_RTOS_NS);

int rtos_ext4_error_notifier_unregister(struct notifier_block *nb)
{
	return blocking_notifier_chain_unregister(&ext4_error_notify_chain, nb);
}
EXPORT_SYMBOL_NS(rtos_ext4_error_notifier_unregister, HW_RTOS_NS);

void ext4_error_notify(struct super_block *sb)
{
	struct rtos_ext4_notify_info rtos_notify_info;

	rtos_save_notify_info(sb, &rtos_notify_info);
	blocking_notifier_call_chain(&ext4_error_notify_chain, 0, &rtos_notify_info);
}
#endif